import json
import uuid
from django.conf import settings
from django.db.models import Q
from django.http import JsonResponse, FileResponse
from django.utils.decorators import method_decorator
from django.views import View
from utils.qiniu_manage import QiniuManage
from examination.models import *
from user.models import *
from django_system.role_recognize import check_permission
from zhineng.models import *
import pandas as pd
import os


def connect_qiniu():
    qn_cli = QiniuManage(settings.AK, settings.SK, settings.BN)
    return qn_cli


class AttendExam(View):
    @method_decorator(check_permission(['学生']))
    def get(self, request):
        college = User.objects.filter(username=request.user).first().classes_user.first().colleges
        test_papers = list(ExaminationPaper.objects.filter(college=college).order_by('-create_time').all().values(
            'id', 'title', 'start_time', 'end_time'))
        test_results = [i['examination_paper_id'] for i in list(
            TestResult.objects.filter(answer_user=User.objects.get(username=request.user)).all().values())]
        for i in test_papers:
            if i['id'] in test_results:
                i['is_ok'] = True
            else:
                i['is_ok'] = False

        return JsonResponse({'college': test_papers, 'code': 201})

    @method_decorator(check_permission(['学生']))
    def post(self, request):
        data = json.loads(request.body)
        selectable_questions_list = [i for i in data['answer_list'] if i['question_type'] != '简答题']
        short_answer_list = [i for i in data['answer_list'] if i['question_type'] == '简答题']
        user = User.objects.filter(username=request.user).first()
        paper = ExaminationPaper.objects.filter(id=data['paper_id']).first()
        right_answer = json.loads(paper.answer)
        score_list = {}
        for q in selectable_questions_list:
            if q['question_type'] not in score_list:
                score_list[q['question_type']] = 0
        for i in right_answer:
            for k in selectable_questions_list:
                # if k['question_type'] == '单选题':
                if k['q_id'] == i['id']:
                    if k['question_type'] == '单选题':
                        if k['answer'] == json.loads(i['answer'])[0]:
                            score_list['单选题'] += int(k['score'])
                    if k['question_type'] == '多选题':
                        if set(k['answer']) == set(json.loads(i['answer'])):
                            score_list['多选题'] += int(k['score'])
                    if k['question_type'] == '填空题':
                        if k['answer'] == i['answer']:
                            score_list['填空题'] += int(k['score'])
        score_list['总分'] = sum(score_list.values())
        result = "您的分数为：" + "，".join([f"{k}: {v}分" for k, v in score_list.items()])

        try:
            test_result = TestResult.objects.create(answer_info=json.dumps(data['answer_list'], ensure_ascii=False),
                                                    examination_paper=paper, answer_user=user,
                                                    score=json.dumps(score_list, ensure_ascii=False))
            if not short_answer_list:
                test_result.is_corrected = True
                test_result.save()
            else:
                date = datetime.now()
                date_now = date.strftime("%Y-%m-%d")
                u_id = uuid.uuid4()
                test_result.file_id = f'{user.username}_{paper.title}_{date_now}'
                test_result.save()
                df = pd.DataFrame(short_answer_list)
                folder_path = os.path.join(settings.BASE_DIR, 'file')
                if not os.path.exists(folder_path):
                    os.mkdir(folder_path)
                file_path = os.path.join(folder_path, f'{user.username}_{paper.title}_{date_now}.xlsx')
                qc = connect_qiniu()
                df.to_excel(file_path, index=False)
                ret, info = qc.upload_file(file_name=f'{user.username}_{paper.title}_{date_now}.xlsx',
                                           file_path=os.path.join(folder_path,
                                                                  f'{user.username}_{paper.title}_{date_now}.xlsx'))
            return JsonResponse({'code': 201, 'msg': '提交成功', 'result': result})
        except Exception as e:
            return JsonResponse({'code': 401, 'msg': f'提交失败原因是{e}'})

    def put(self, request):
        paper_id = json.loads(request.body)['id']
        paper = ExaminationPaper.objects.filter(id=paper_id).first()
        start_time = paper.start_time
        end_time = paper.end_time
        now = datetime.now()
        if start_time <= now < end_time:
            return JsonResponse({'code': 201, 'msg': '可以开始答题'})
        else:
            return JsonResponse({'code': 30, 'msg': '当前不在考试时间范围内'})


class GetPaperInfo(View):
    def get(self, request):
        paper_id = int(request.GET['paper_id'])
        paper = ExaminationPaper.objects.filter(id=paper_id).first()
        paper_info = {
            'id': paper.id,
            'title': paper.title,
            'create_time': paper.create_time,
            'questions_info': paper.questions_info
        }
        empty_answer_list = []
        for i in json.loads(paper_info['questions_info']):
            if i['question_type'] == '多选题':
                empty_answer_list.append(
                    {'q_id': i['id'], 'answer': [], 'score': i['score'], 'question_type': i['question_type']})
            else:
                empty_answer_list.append(
                    {'q_id': i['id'], 'answer': '', 'score': i['score'], 'question_type': i['question_type']})
        return JsonResponse({'code': 201, 'data': paper_info, 'empty_answer': empty_answer_list})


class UnreviewedResult(View):
    """
    获取需要单独批改的试卷简答题结果并打分
    """

    @method_decorator(check_permission(['老师']))
    def get(self, request):
        all_user = User.objects.filter(username=request.user).first().classes_user.first().user.all()
        need_correction_list = TestResult.objects.filter(Q(answer_user__in=all_user) & Q(is_corrected=False))
        result_list = [
            {'answer_user': i.answer_user.username, 'test_paper': i.examination_paper.title,
             'create_time': i.create_time, 'score': i.score, 'is_corrected': i.is_corrected,
             'file_id': i.file_id, 'id': i.id} for i in need_correction_list]
        return JsonResponse({'code': 200, 'msg': 'ok!!!', 'data': result_list})

    @method_decorator(check_permission(['老师']))
    def post(self, request):
        file_id = json.loads(request.body).get('file_id')
        file_name = file_id + '.xlsx'
        qn_cli = connect_qiniu()
        url = qn_cli.download_file(file_name)
        return JsonResponse({'code': 201, 'msg': 'ok', 'url': url})

    @method_decorator(check_permission(['老师']))
    def put(self, request):
        data = json.loads(request.body)
        try:
            test_result = TestResult.objects.get(id=data['paper_id'])
            test_result.is_corrected = True
            answer = json.loads(test_result.score)
            answer['简答题'] = data['score']
            total_score = answer['总分']
            del answer['总分']
            answer['总分'] = int(data['score']) + total_score
            test_result.score = json.dumps(answer, ensure_ascii=False)
            test_result.save()
            return JsonResponse({'code': 200, 'msg': '打分成功'})
        except Exception as e:
            return JsonResponse({'code': 401, 'msg': str(e)})
